package pers.vic.rpc.registry.zookeeper;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.x.discovery.ServiceDiscovery;
import org.apache.curator.x.discovery.ServiceDiscoveryBuilder;
import org.apache.curator.x.discovery.ServiceInstance;
import org.apache.curator.x.discovery.details.JsonInstanceSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pers.vic.rpc.registry.IRegistry;
import pers.vic.rpc.registry.model.RpcUrl;

import java.util.Collection;
import java.util.List;

/**
 * 描述:基于zookeeper的注册中心
 * @author Vic.xu
 * @date 2022-02-10 16:24
 */
public class ZookeeperRegistry implements IRegistry {

    private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperRegistry.class);

    //根节点
    private static final String REGISTRY_PATH = "/xqd-registry";
    /**
     * [zk 10之：Curator之三：服务的注册及发现 - duanxz - 博客园 (cnblogs.com)](https://www.cnblogs.com/duanxz/p/3783893.html)
     */

    //Curator中提供的服务注册与发现的组件封装
    private final ServiceDiscovery<RpcUrl> serviceDiscovery;

    /**
     * 根据注册中心地址构件对象
     * @param registryAddress
     * @throws Exception
     */
    public ZookeeperRegistry(String registryAddress) throws Exception {
        CuratorFramework client= CuratorFrameworkFactory
                .newClient(registryAddress,new ExponentialBackoffRetry(1000,3));
        client.start();
        JsonInstanceSerializer<RpcUrl> serializer=new JsonInstanceSerializer<>(RpcUrl.class);
        this.serviceDiscovery = ServiceDiscoveryBuilder.builder(RpcUrl.class)
                .client(client)
                .serializer(serializer)
                .basePath(REGISTRY_PATH)
                .build();
        serviceDiscovery.start();

    }

    @Override
    public void register(RpcUrl url) throws Exception {
        LOGGER.info("注册服务：{}", url);
        ServiceInstance<RpcUrl> serviceInstance = ServiceInstance.<RpcUrl>builder()
                .name(url.getServerName())
                .address(url.getAddress())
                .port(url.getPort())
                .payload(url)
                .build();
        serviceDiscovery.registerService(serviceInstance);
    }

    @Override
    public void unRegister(RpcUrl url) throws Exception {
        ServiceInstance<RpcUrl> serviceInstance = ServiceInstance.<RpcUrl>builder()
                .name(url.getServerName())
                .address(url.getAddress())
                .port(url.getPort())
                .payload(url)
                .build();
        serviceDiscovery.unregisterService(serviceInstance);
    }

    @Override
    public RpcUrl discovery(String serverName) throws Exception {
        Collection<ServiceInstance<RpcUrl>> serviceInstances= serviceDiscovery
                .queryForInstances(serverName);
        //TODO  负载均衡
        List<ServiceInstance<RpcUrl>> instanceList = (List<ServiceInstance<RpcUrl>>) serviceInstances;
        System.out.println(instanceList.size());

        return instanceList.get(0).getPayload();
    }

    public static void main(String[] args) throws Exception {
        RpcUrl url = new RpcUrl("xqd-rpc-1","127.0.0.1", 9999);
        RpcUrl url2 = new RpcUrl("xqd-rpc-1","127.0.0.2", 9999);
        String address = "localhost:2181";
        ZookeeperRegistry zookeeperRegister = new ZookeeperRegistry(address);
        zookeeperRegister.register(url);
        zookeeperRegister.register(url2);
        RpcUrl discovery = zookeeperRegister.discovery("xqd-rpc-1");
        System.out.println(discovery);
        Thread.sleep(10000);
        System.out.println("end");
    }
}
